package com.coder4j.starter.mybatis;

import com.coder4j.utils.DateUtils;
import com.coder4j.utils.StringUtils;
import com.coder4j.starter.web.BaseRequest;
import lombok.Data;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.time.LocalDate;
import java.util.Date;

/**
 * 基本查询
 *
 * @author Keller
 * @date 2021-06-21 13:46:58
 */
@Data
public abstract class BaseQuery<T> {
    /**
     *
     */
    private Long id;
    /**
     * 修改人ID
     */
    private Long updateId;

    /**
     * 修改人名称
     */
    private String updateName;

    /**
     * 修改时间
     */
    private Date updateTime;

    /**
     * 创建人ID
     */
    private Long createId;

    /**
     * 创建人名称
     */
    private String createName;

    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 是否删除 0 未删除,1 已删除
     */
    private Integer isDeleted;

    /**
     * 表名
     */
    private String tableName;

    /**
     * 页面大小
     */
    private int pageSize = 15;
    /**
     * 要查询的页码
     */
    private int pageNo = 1;
    private int pageNum = 1;
    /**
     * 根据页面大小和要查询的页码计算出的起始行号
     */
    private int offset;

    /**
     * 查询起始时间
     */
    private Date queryStartTime;

    /**
     * 查询结束时间
     */
    private Date queryEndTime;

    /**
     * 默认排序
     */
    private String defaultOrder;

    /**
     * 默认查询条件
     */
    private String defaultCondition;

    /**
     * 默认的组织路径，用于数据范围控制
     */
    private String defaultOrganizationPath;

    /**
     * 默认表别名
     */
    private String defaultAliasTableName;

    /**
     * 忽略数据权限
     */
    private String defaultIgnoreDataScope;


    public static final int MAX_SIZE = 1000;

    public int getPageSize() {
        if (pageSize <= 0) {
            return 0;
        }
        if (pageSize > MAX_SIZE) {
            return MAX_SIZE;
        }
        return pageSize;
    }

    public int getPageNo() {
        //前端可能会用 pageNo 、 pageNum 中的一个，如果发现 pageNo是默认值，且和 pageNum不一样，以pageNum为准
        if(pageNo == 1 && pageNo != pageNum){
            pageNo = pageNum;
        }
        return pageNo <= 0 ? 1 : pageNo;
    }

    public int getOffset() {
        return (getPageNo() - 1) * getPageSize();
    }

    public <K extends BaseRequest> void initTimeQuery(K request) {
        if (StringUtils.notEmpty(request.getStartTime())) {
            this.queryStartTime = DateUtils.localDate2Date(LocalDate.parse(request.getStartTime()));
        }
        if (StringUtils.notEmpty(request.getEndTime())) {
            this.queryEndTime = DateUtils.localDate2Date(LocalDate.parse(request.getEndTime()).plusDays(1));
        }
    }


    public synchronized T getEntityInstance() {
        Type genType = this.getClass().getGenericSuperclass();
        if (genType instanceof ParameterizedType) {
            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
            Class<T> clazz = (Class<T>) params[0];
            try {
                return clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return null;
    }
}
